package main

import "log"

var (
	p *int
)

/**
声明一个指针变量：
指针的零值是nil，所有未初始化的指针变量的值都是nil，在指针没有指向（未被初始化）之前，
不能对(*pointer)进行读写操作，否则会报空指针异常：
*/

func nilTest() {
	//p = &100
	log.Println(p)
}
func zhizhen() {
	//1、声明一个变量，输出变量的值，变量的类型、变量的地址
	a := 100
	log.Println("a的数值=", a)
	log.Printf("a的类型=%T", a)
	log.Printf("a的地址是=%v", &a)

	//2、创建一个指针变量
	var i *int
	log.Println("指针变量=", i)    //指针变量的初始值
	i = &a                     //i指向a的内存地址
	log.Println("i的数值=", i)    //i中存储的是a的地址
	log.Printf("i的类型=%T", i)   //输出是的指针内类型
	log.Printf("i的地址是=%v", &i) //指针类型 本身也是由内存地址的

	//3、操作变量改变数值---> 通过变量本身
	a = 1000
	log.Println("a的数值=", a)
	log.Printf("a的类型=%T", a)
	log.Printf("a的地址是=%v", &a)

	//4、通过指针 改变变量的数值
	*i = 2000
	log.Println("a的值=", a)

	//5、指针的指针
	var p **int
	log.Println("指针的指针=", p)
	p = &i //将指针的类型 赋值 指针的指针的类型,其实就是的指针的指针 也是放了一个地址
	log.Printf("%T,%T,%T,a=%v,p=%v", p, i, a, a, p)

}

//数组指针
func shuzuzhizhen() {
	arr1 := [4]int{2, 3, 4, 54}
	log.Println("arr1=", arr1)
	var arr2 *[4]int
	arr2 = &arr1
	log.Printf("arr2=%v", arr2)
}

//指针类型的数组
func zhizhenshuzu() {
	a := 1
	b := 2
	c := 3
	d := 4
	arr3 := [4]*int{&a, &b, &c, &d}

	log.Printf("指针数组=%v", arr3)
	*arr3[2] = 1009
	log.Printf("指针数组=%v", arr3)
}
func main() {

	nilTest()
	Test()
	zhizhen()
	shuzuzhizhen()
	zhizhenshuzu()
}

func Test() {
	//声明字符串
	str := "hello world"
	log.Printf("声明的字符串为=%s,类型为=%T", str, str)
	//获取字符串的地址
	add := &str
	log.Printf("字符串的地址=%v,类型为=%T", add, add)
	//获取地址的值
	s := *add
	log.Printf("地址=%v 对应的值=%v,类型为=%T", add, s, s)
}
